﻿using MahApps.Metro.Controls;
using ReflectionStudio.Core.Events;
using ReflectionStudio.Core.FTPClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;
using WPFExcelReport;
namespace ReflectionStudio.Components.UserControls
{
    /// <summary>
    /// DocumentBase is the based class for all Document user controls
    /// </summary>
    public class DocumentBase:MetroContentControl
    {
        #region ==IsExpandAll===========
        public static readonly DependencyProperty IsExpandAllProperty = DependencyProperty.Register("IsExpandAll",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsExpandAllChanged));
        public bool IsExpandAll
        {
            get
            {
                return (bool)GetValue(IsExpandAllProperty);
            }
            set
            {
                SetValue(IsExpandAllProperty, value);
            }
        }
        private static void OnIsExpandAllChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsExpandAll = (bool)e.NewValue;
            }
        }
        #endregion
        #region ==INFO===========
        public static readonly DependencyProperty INFOProperty = DependencyProperty.Register("INFO",
            typeof(string), typeof(DocumentBase),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnINFOChanged));
        public string INFO
        {
            get
            {
                return (string)GetValue(INFOProperty);
            }
            set
            {
                SetValue(INFOProperty, value);
            }
        }
        private static void OnINFOChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.INFO = (string)e.NewValue;
            }
        }

        #endregion

        #region ==IsCanDelete===========
        public static readonly DependencyProperty IsCanDeleteProperty = DependencyProperty.Register("IsCanDelete",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCanDeleteChanged));
        public bool IsCanDelete
        {
            get
            {
                return (bool)GetValue(IsCanDeleteProperty);
            }
            set
            {
                SetValue(IsCanDeleteProperty, value);
            }
        }
        private static void OnIsCanDeleteChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsCanDelete = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==IsCanNew===========
        public static readonly DependencyProperty IsCanNewProperty = DependencyProperty.Register("IsCanNew",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCanNewChanged));
        public bool IsCanNew
        {
            get
            {
                return (bool)GetValue(IsCanNewProperty);
            }
            set
            {
                SetValue(IsCanNewProperty, value);
            }
        }
        private static void OnIsCanNewChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsCanNew = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==IsCanChg===========
        public static readonly DependencyProperty IsCanChgProperty = DependencyProperty.Register("IsCanChg",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCanChgChanged));
        public bool IsCanChg
        {
            get
            {
                return (bool)GetValue(IsCanChgProperty);
            }
            set
            {
                SetValue(IsCanChgProperty, value);
            }
        }
        private static void OnIsCanChgChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsCanChg = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==IsCanCopy===========
        public static readonly DependencyProperty IsCanCopyProperty = DependencyProperty.Register("IsCanCopy",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCanCopyChanged));
        public bool IsCanCopy
        {
            get
            {
                return (bool)GetValue(IsCanCopyProperty);
            }
            set
            {
                SetValue(IsCanCopyProperty, value);
            }
        }
        private static void OnIsCanCopyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsCanCopy = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==IsCanManage===========
        public static readonly DependencyProperty IsCanManageProperty = DependencyProperty.Register("IsCanManage",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCanManageChanged));
        public bool IsCanManage
        {
            get
            {
                return (bool)GetValue(IsCanManageProperty);
            }
            set
            {
                SetValue(IsCanManageProperty, value);
            }
        }
        private static void OnIsCanManageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsCanManage = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==ScopeManage===========
        public static readonly DependencyProperty ScopeManageProperty = DependencyProperty.Register("ScopeManage",
            typeof(string), typeof(DocumentBase),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnScopeManageChanged));
        public string ScopeManage
        {
            get
            {
                return (string)GetValue(ScopeManageProperty);
            }
            set
            {
                SetValue(ScopeManageProperty, value);
            }
        }
        private static void OnScopeManageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.ScopeManage = (string)e.NewValue;
            }
        }
        #endregion

        #region ==IsShowLeft===========
        public static readonly DependencyProperty IsShowLeftProperty = DependencyProperty.Register("IsShowLeft",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsShowLeftChanged));
        public bool IsShowLeft
        {
            get
            {
                return (bool)GetValue(IsShowLeftProperty);
            }
            set
            {
                SetValue(IsShowLeftProperty, value);
                 
            }
        }
        private static void OnIsShowLeftChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsShowLeft = (bool)e.NewValue;
            }
        }
        #endregion
        #region ==IsShowRight===========
        public static readonly DependencyProperty IsShowRightProperty = DependencyProperty.Register("IsShowRight",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsShowRightChanged));
        public bool IsShowRight
        {
            get
            {
                return (bool)GetValue(IsShowRightProperty);
            }
            set
            {
                SetValue(IsShowRightProperty, value);
               
            }
        }
        private static void OnIsShowRightChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsShowRight = (bool)e.NewValue;
            }
        }
        #endregion
        #region ==IsShowTop===========
        public static readonly DependencyProperty IsShowTopProperty = DependencyProperty.Register("IsShowTop",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsShowTopChanged));
        public bool IsShowTop
        {
            get
            {
                return (bool)GetValue(IsShowTopProperty);
            }
            set
            {
                SetValue(IsShowTopProperty, value);
               
            }
        }
        private static void OnIsShowTopChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsShowTop = (bool)e.NewValue;
            }
        }
        #endregion
        #region ==IsShowBottom===========
        public static readonly DependencyProperty IsShowBottomProperty = DependencyProperty.Register("IsShowBottom",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsShowBottomChanged));
        public bool IsShowBottom
        {
            get
            {
                return (bool)GetValue(IsShowBottomProperty);
            }
            set
            {
                SetValue(IsShowBottomProperty, value); 
            }
        }
        private static void OnIsShowBottomChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsShowBottom = (bool)e.NewValue;
            }
        }
        #endregion
        #region ==IsBusy===========
        public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register("IsBusy",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsBusyChanged));
        public bool IsBusy
        {
            get
            {
                return (bool)GetValue(IsBusyProperty);
            }
            set
            {
                SetValue(IsBusyProperty, value);
            }
        }
        private static void OnIsBusyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsBusy = (bool)e.NewValue;
            }
        }
        #endregion

        #region ==WFID===========
        public static readonly DependencyProperty WFIDProperty = DependencyProperty.Register("WFID",
            typeof(string), typeof(DocumentBase),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnWFIDChanged));
        public string WFID
        {
            get
            {
                return (string)GetValue(WFIDProperty);
            }
            set
            {
                SetValue(WFIDProperty, value);
                OnWorkflowIDChange(value);
            }
        }
        private static void OnWFIDChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.WFID = (string)e.NewValue;
            }
        }

        #endregion
        #region ==IsNewWF===========
        public static readonly DependencyProperty IsNewWFProperty = DependencyProperty.Register("IsNewWF",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsNewWFChanged));
        public bool IsNewWF
        {
            get
            {
                return (bool)GetValue(IsNewWFProperty);
            }
            set
            {
                SetValue(IsNewWFProperty, value);
            }
        }
        private static void OnIsNewWFChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsNewWF = (bool)e.NewValue;
                src.NewWFChg((bool)e.NewValue);
            }
        }
        public virtual void NewWFChg(bool value)
        { 
            
          
        }
        #endregion 
        
        #region ==NWFID===========

        public static readonly DependencyProperty NWFIDProperty = DependencyProperty.Register("NWFID",
            typeof(string), typeof(DocumentBase),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnNWFIDChanged));
        public string NWFID
        {
            get
            {
                return (string)GetValue(NWFIDProperty);
            }
            set
            {
                SetValue(NWFIDProperty, value); 
             }
        }

        private static void OnNWFIDChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.NWFID = (string)e.NewValue;
                src.OnNWFIDChg((string)e.NewValue);
            }
        }

        public virtual void OnNWFIDChg(string value)
        {
         
        }

        #endregion

        #region ==dwMaster===========
        public static readonly DependencyProperty dwMasterProperty = DependencyProperty.Register("dwMaster",
            typeof(DataRow), typeof(DocumentBase),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OndwMasterChanged));
        public DataRow dwMaster
        {
            get
            {
                return (DataRow)GetValue(dwMasterProperty);
            }
            set
            {
                SetValue(dwMasterProperty, value);
                OnMasterChg(value);
            }
        }
        private static void OndwMasterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.dwMaster = (DataRow)e.NewValue;
            }
        }
        public virtual void OnMasterChg(DataRow row)
        { }
        #endregion
        #region ==IsChanged===========
        public static readonly DependencyProperty IsChangedProperty = DependencyProperty.Register("IsChanged",
            typeof(bool), typeof(DocumentBase),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsChangedChanged));
        public bool IsChanged
        {
            get
            {
                return (bool)GetValue(IsChangedProperty);
            }
            set
            {
                SetValue(IsChangedProperty, value);
            }
        }
        private static void OnIsChangedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var src = sender as DocumentBase;
            if (src != null)
            {
                src.IsChanged = (bool)e.NewValue;
                src.OnChanged((bool)e.NewValue);
            }
        }
        public virtual void OnChanged(bool value)
        {

        }
        #endregion
        public string RUNID="";
        public DataRow dwWFEvent = null;
        public DatePicker dateChooser;
        public FTPClient ftpClient = null;
       

        #region ----------------CONSTRUCTOR----------------
        public virtual void OnWorkflowIDChange(string wfid)
        { 
        }
        public virtual void OnWorkflowIDChange(MessageEventArgs e)
        {
        }
        /// <summary>
        /// Constructor
        /// </summary>
        public DocumentBase()
        {

            Loaded += Window_Loaded;
        }

        public virtual void Window_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        public virtual void SetUp(Dictionary<string, object> dicParamater)
        {

        }
        /// <summary>
        /// Plug the load event
        /// </summary>
        /// <param name="e"></param>
        /*protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            this.Loaded += new RoutedEventHandler(DocumentBase_Loaded);
        }
        */
        #endregion

        #region ----------------PROPERTIES---------------- 

        /// <summary>
        /// Content data
        /// </summary>
        public object ContentData { get; set; }

        /// <summary>
        /// Flag property that indicate if the document content is loaded
        /// </summary>
        public bool IsLoaded { get; set; }

        /// <summary>
        /// BackgroundWorker variable
        /// </summary>
        protected BackgroundWorker _Worker = null;

        /// <summary>
        /// Internal BackgroundWorker that can be used for document loading
        /// </summary>
        protected BackgroundWorker Worker
        {
            get
            {
                if (_Worker == null)
                {
                    _Worker = new BackgroundWorker();
                    _Worker.WorkerReportsProgress = false;
                    _Worker.WorkerSupportsCancellation = false;

                }
                return _Worker;
            }
        }

        #endregion

        public delegate void LOADBYAUFDelegate();
     

          public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key)
        {
            try
            {
                XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement;
                EncryptedXml eXml = new EncryptedXml();
                byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false);
                EncryptedData edElement = new EncryptedData();
                edElement.Type = EncryptedXml.XmlEncElementUrl;
                string encryptionMethod = null;

                if (Key is TripleDES)
                {
                    encryptionMethod = EncryptedXml.XmlEncTripleDESUrl;
                }
                else if (Key is DES)
                {
                    encryptionMethod = EncryptedXml.XmlEncDESUrl;
                }
                if (Key is Rijndael)
                {
                    switch (Key.KeySize)
                    {
                        case 128:
                            encryptionMethod = EncryptedXml.XmlEncAES128Url;
                            break;
                        case 192:
                            encryptionMethod = EncryptedXml.XmlEncAES192Url;
                            break;
                        case 256:
                            encryptionMethod = EncryptedXml.XmlEncAES256Url;
                            break;
                    }
                }
                edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
                edElement.CipherData.CipherValue = encryptedElement;
                EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public static void Decrypt(XmlDocument Doc, SymmetricAlgorithm Alg)
        {
            try
            {
                XmlElement encryptedElement = Doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
                EncryptedData edElement = new EncryptedData();
                edElement.LoadXml(encryptedElement);
                EncryptedXml exml = new EncryptedXml();
                byte[] rgbOutput = exml.DecryptData(edElement, Alg);
                exml.ReplaceData(encryptedElement, rgbOutput);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }

        public virtual void SetUpUserRight()
        {
            AllPossible();
        }
        private void AllPossible()
        {
            IsCanDelete = true;
            IsCanNew = true;
            IsCanChg = true;
            IsCanCopy = true;
            IsCanManage = true;
            ScopeManage = "*";
        }
    }
}